<template>
  <div id="contentToConvert" class="contentToConvert" style="width:100%;height:100%;background: #17273e;">
    <el-row class="top_control">
      <div class="well-name">{{ wellName }}</div>
      <div class="wellrednum">{{ isredrill }}</div>
      <el-dropdown :hide-on-click="false" style="margin: 0 10px" trigger="click">
        <el-button v-show="isEditting" type="primary">Canvas Size</el-button>
        <template #dropdown>
          <el-dropdown-menu>
            <el-dropdown-item>
              width：&nbsp;
              <el-input-number v-model="canvasSizeConfig.width" :max="500" :min="100" :step="10" style="width: 10rem"
                @change="canvasSizeChange"></el-input-number>
              &nbsp;%
            </el-dropdown-item>
            <el-dropdown-item>
              height：
              <el-input-number v-model="canvasSizeConfig.height" :max="500" :min="100" :step="10" style="width: 10rem"
                @change="canvasSizeChange"></el-input-number>
              &nbsp;%
            </el-dropdown-item>
          </el-dropdown-menu>
        </template>
      </el-dropdown>
      <template v-if="isEditting">
        <el-button type="primary" @click="alignLeft">Align Left</el-button>
        <!-- <el-button type="primary" @click="alignRight">Align Right</el-button> -->
        <el-button type="primary" @click="alignTop">Align Top</el-button>
        <!-- <el-button type="primary" @click="openInportDialog">
          Import Well Configuration
        </el-button> -->
        <el-dropdown style="margin: 0 10px" trigger="click" @command="addControl">
          <el-button type="primary">AddControl</el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item v-for="(item, index) in iconComponents" :key="index" :command="index">
                {{
                  item.remark
                }}
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
        </el-dropdown>
        <el-button type="primary" @click="submit()">Submit</el-button>
        <el-button plain type="primary" @click="cancel()">Cancel</el-button>
      </template>
      <template v-else>
        <!-- <el-dropdown style="margin: 0 10px" trigger="click" @command="handleCommand">
          <el-button type="primary">WellPair</el-button>
          <template #dropdown>
            <el-dropdown-menu>
              <el-dropdown-item v-for="item in setValueData" :key="item.id" :command="item.id">
                {{ item.label }}
              </el-dropdown-item>
            </el-dropdown-menu>
          </template>
</el-dropdown> -->
        <div style="display: flex;">
          <!-- <span style="color: #fff;line-height: 2.1rem;margin-right: 0.5rem;">user tags trend</span>
          <el-switch v-model="isUser" style="margin-right: 1rem;" @change="changeTrend" active-color="#13ce66"
            inactive-color="#ff4949">
          </el-switch> -->
          <span v-show="false">{{ setid }}</span>
          <span style="color: #fff;line-height: 2.1rem;margin-right: 0.5rem;font-size:10px"
            v-if="setid !== '1'">Pad:</span>
          <el-select v-model="padValue" placeholder="Please Select" style="width: 100px;margin-right: 10px;"
            class="onlayselect" @change="padChange">
            <el-option v-for="option in optionsOne" :key="option.id" :label="option.name" :value="option.id">
            </el-option>
          </el-select>
          <span style="color: #fff;line-height: 2.1rem;margin-right: 0.5rem;font-size:10px">WellPair:</span>
          <el-select v-model="selectedValue" placeholder="Please Select" @change="handleCommand"
            style="width: 120px;margin-right: 10px;" class="onlayselect">
            <el-option v-for="option in optionsTwo" :key="option.id" :label="option.name" :value="option.id">
            </el-option>
          </el-select>
          <!-- <span style="color: #fff;line-height: 2.1rem;margin-right: 0.5rem;">Switching Well:</span>
          <el-select v-model="selectedValue" filterable @focus="groundItem" placeholder="Please Select"
            @change="handleCommand" style="width: 150px;margin-right: 10px;" class="onlayselect">
            <el-option v-for="item in setValueData" :key="item.id" :label="item.label" :value="item.id">
            </el-option>
          </el-select> -->
          <el-button type="primary" @click="presetFormulas">Calculation Tag</el-button>
          <el-button type="primary" @click="openFavoriteList">Favorite List</el-button>
          <el-button type="primary" @click="exportHistory">Export Well History</el-button>
          <el-button type="primary" @click="openEspTrend">ESP Trend</el-button>
          <el-button type="primary" @click="goBack">Back</el-button>
          <el-button type="primary" @click="edit">Edit</el-button>
        </div>
      </template>
    </el-row>
    <!--commit-->
    <div id="d3CanvasView">
      <div id="left_card" v-if="isEditting == true">
        <div id="numericheading">Binding Value</div>
        <div style="border-bottom: 1px solid rgba(255, 255, 255, 0.1);">
          <div class="binding-item" v-for="(item, index) in bindingList" :key="index" @click="dataSection(index)">
            <img v-if="item.img" :src="item.img" class="binding-img" alt="binding icon">
            <span class="binding-label">{{ item.remark }}</span>
          </div>
        </div>
        <div id="numericheading">Image Area</div>
        <div class="binding-container-img">
          <LeftComponents :getSvg="getSvg" />
        </div>
        <div id="numericheading">Drawing Pages</div>
        <div style="border-bottom: 1px solid rgba(255, 255, 255, 0.1);">
          <div class="binding-item" v-for="(item, index) in StoragePages" :key="index" @click="onCopyClick(index)">
            <img v-if="item.img" :src="item.img" class="binding-img" alt="binding icon"
              style="height: 60px;width: 100px;">
            <span class="binding-label">{{ item.remark }}</span>
          </div>
        </div>
      </div>
      <div id="d3Canvas" :style="{
        overflowX: Number(canvasSizeConfig.width) === 100 ? 'hidden' : 'auto',
        overflowY: Number(canvasSizeConfig.height) === 100 ? 'hidden' : 'auto',
        flex: rightCardCollapsed ? '1' : '',
      }" />
      <div v-if="isEditting == true" id="rightToggleBtn" @click="toggleRightCard"
        :style="{ display: rightCardVisable ? 'flex' : 'none' }">
        {{ rightCardCollapsed ? '→' : '←' }}
      </div>
      <div id="right-card" v-if="isEditting == false">
        <div>
          <div class="well-status">
            Well Test:
            <span :style="{ color: wellTestStatusFlagColor }" class="flag">
              {{ wellTestStatusFlag }}
            </span>
          </div>
          <CustomCard v-if="rightCardVisable" :data="wellData" :isEditting="isEditting" :rightProps="rightProps"
            :tagTypesList="tagTypesList" :tagsList="tagsList" @handleMouseOut="handleMouseOut"
            @handleMouseEnter="handleMouseEnter" @getTagByKeyType="getTagByKeyType" @setCard="setCard"
            :prouendId="productionid" />
        </div>
        <ScrollModel :changeData="changeData" :dataList="scrollModelData" :wellName="wellnameid" />
      </div>
      <div id="right-card" :style="{
        width: rightCardCollapsed ? '0' : '20%',
        overflow: 'hidden'
      }" v-if="isEditting == true">
        <div>
          <div class="well-status">
            Well Test:
            <span :style="{ color: wellTestStatusFlagColor }" class="flag">
              {{ wellTestStatusFlag }}
            </span>
          </div>
          <CustomCard v-if="rightCardVisable" :data="wellData" :isEditting="isEditting" :rightProps="rightProps"
            :tagTypesList="tagTypesList" :tagsList="tagsList" @handleMouseOut="handleMouseOut"
            @handleMouseEnter="handleMouseEnter" @getTagByKeyType="getTagByKeyType" @setCard="setCard"
            :prouendId="productionid" />
        </div>
        <ScrollModel :changeData="changeData" :dataList="scrollModelData" :wellName="wellnameid" />
      </div>
    </div>
    <FormulaDialog v-model="dialogVisible" :f-tag="formulaTag" :form-value="form" :list="list"
      :tag-types-list='tagTypesList' :tags-list='tagsList' :formula-list="formulaList" :well-id="detailData.wellId"
      @confirm="changeTag" :uuid-list="uuindValue" :tagsname="tagsName" />
    <div v-if="isTrendpad" class="dialog">
      <div class="dialog-title">{{ espname }} - ESP Trend </div>
      <div class="el-icon-close i-right" @click="completion">
        <el-icon>
          <Close />
        </el-icon>
      </div>

      <div class="dialog-box">
        <Trendpad :wellIdnumber="wellidNum" :list="list" :padname="wellName" @child-event="handleChildEvent" />
      </div>
    </div>
    <div v-if="isTrendtag" class="dialog" style="border: 1px solid #f00">
      <div class="dialog-title">{{ handletitle }}</div>
      <div class="el-icon-close i-right" @click="completion">
        <el-icon>
          <Close />
        </el-icon>
      </div>
      <div class="dialog-box">
        <Trendtag :keyType="keyType" :tagName="tagName" :tagType="tagType" :unit="unit" @sendData="handleData" />
      </div>
    </div>
    <div v-if="hoverData" class="tooltip-content" :style="{ left: tooltipX - 100 + 'px', top: tooltipY + 'px' }">
      <div><span>Tag：</span>{{ activeTooltip.key }}</div>
      <div><span>Unit：</span>{{ activeTooltip.unit }}</div>
      <div class="tooltip-row"><span>Desc：</span>{{ activeTooltip.desc }}</div>
    </div>
    <el-dialog v-model="importWellDialogVisible" title="Import Well Configuration" width="600px"
      style="border: 1px solid #f00">
      <el-form label-width="120px">
        <el-form-item label="Origin Well">
          <el-select v-model="originWellId" filterable placeholder="Please select" @change="onSelectWellChange($event)">
            <el-option v-for="item in list" :key="item.id" :label="item.wellShowName" :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="Preview">
          <el-image v-if="previewSrcList.length > 0" :initial-index="4" :max-scale="7" :min-scale="0.2"
            :preview-src-list="previewSrcList" :src="previewSrcList[0]" :zoom-rate="1.2" fit="cover"
            style="width: 100px; height: 100px" />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="importWellDialogVisible = false">Cancel</el-button>
        <el-button type="primary" @click="onCopyClick">Submit</el-button>
      </template>
    </el-dialog>
    <ImgTextDialog v-model:visible="imgTextDialogVisible" :form='imgTextDialogParams.params' />
    <div v-show="contextMenu.visible" id="contextMenuContainer"
      :style="{ left: contextMenu.left + 10 + 'px', top: contextMenu.top - 10 + 'px' }">
      <div>
        ZLevel：
        <el-input v-model="contextMenu.zIndex" style="display: inline-block;width: 30px;height: 100%;text-align: center"
          type="text" @change="zLevelChange" />
      </div>
    </div>
    <el-dialog v-model="favoriteDialogVisible" title="Favorite List" width="500px">
      <el-table :data="favoritaList" style="width: 100%" @row-dblclick="rowDbclickFun">
        <el-table-column prop="name" label="Name" width="150" />
        <el-table-column prop="updateTime" label="UpdateTime" width="180" />
        <el-table-column label="Operate" min-width="120" width="130">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="deleteClick(scope)">
              Delete
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
    <el-dialog v-model="presetFormulasVisible" title="Calculation Tag" width="1400px">
      <div class="preset-well">
        <div>
          <span style="color: #333;line-height: 2.1rem;margin-right: 0.5rem;">Pad:</span>
          <el-select v-model="presePadValue" placeholder="Please Select" style="width: 150px;margin-right: 10px;"
            class="onlayselect" @change="presePadChange">
            <el-option v-for="option in optionsOne" :key="option.id" :label="option.name" :value="option.id">
            </el-option>
          </el-select>
          <span style="color: #333;line-height: 2.1rem;margin-right: 0.5rem;">WellPair:</span>
          <el-select v-model="presetWell" placeholder="Please Select" style="width: 150px;margin-right: 10px;"
            @change="getFormulaManageList" class="onlayselect">
            <el-option v-for="option in preseOptionsTwo" :key="option.id" :label="option.name" :value="option.id">
            </el-option>
          </el-select>
          <!-- <span>Well: </span>
          <el-select v-model="presetWell" filterable placeholder="please select" style="width: 300px" clearable>
            <el-option v-for="option in presetWellList" :key="option.id" :label="option.wellShowName"
              :value="option.id" />
          </el-select> -->
          <!-- <el-button type="primary" size="small" @click="getFormulaManageList" style="margin-left: 10px;">
            Search
          </el-button> -->
        </div>
        <el-button type="primary" size="small" @click="addPreseFormFun">
          New Calculation Tag
        </el-button>
      </div>
      <el-table :data="presetFormulasList" style="width: 100%">
        <el-table-column prop="number" label="No." width="70" />
        <el-table-column prop="wellName" label="Well" width="100" />
        <el-table-column prop="formulaName" label="Calculation Tag" width="150" />
        <el-table-column prop="formulaText" label="Formula" width="200" />
        <el-table-column prop="formulaTags" label="PHD Tag" width="400" />
        <el-table-column prop="description" label="Description" />
        <el-table-column label="Operate" width="150">
          <template #default="scope">
            <el-button link type="primary" size="small" @click="editPreseIdClick(scope.row)">
              <span style="font-size: 12px;">Edit</span>
            </el-button>
            <el-button link type="primary" size="small" @click="formulaManageDeleteFun(scope.row)">
              <span style="font-size: 12px;">Delete</span>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
      <div style=" display: flex;justify-content: flex-end;">
        <el-pagination small @current-change="handlePageChange" :current-page="presetNum" :page-size="presetSize"
          :total="presetTotal" layout="prev, pager, next">
        </el-pagination>
      </div>

    </el-dialog>

    <el-dialog v-model="presetFormVisible" title="New Calculation Tag" width="900px">
      <el-form :model="addPresetForm" ref="formRef" label-width="auto" style="max-width: 900px" :rules="rules">
        <el-form-item label="Well" prop="wellId">
          <el-select v-model="addPresetForm.wellId" :disabled="true" filterable placeholder="please select"
            style="width: 800px" clearable>
            <el-option v-for="option in presetWellList" :key="option.id" :label="option.wellShowName"
              :value="option.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="Name" prop="formulaName">
          <el-input v-model="addPresetForm.formulaName" style="width: 800px;" />
        </el-form-item>
        <el-form-item label="Formula" prop="formulaText">
          <el-input v-model="addPresetForm.formulaText" style="width: 800px;" :rows="4" type="textarea" />
        </el-form-item>
        <el-form-item v-for="(item, index) in pointsList" :key="index" :label="item.name">
          <!-- <el-select v-model="item.tagName" filterable placeholder="please select" style="width: 800px">
            <el-option v-for="option in tagsList" :key="option.id" :label="option.tagName" :value="option.tagName" />
          </el-select> -->
          <el-select v-model="item.tagName" filterable remote @focus="changelist" :remote-method="handleRemoteMethod"
            style="width: 730px;" :loading="loading" ref="select" placeholder="Please select" popper-class="selectCls">
            <div style="margin-left: 15px;font-size: 0.9rem;border-bottom: 1px solid #333;">Tag Name | Unit |
              Description
            </div>
            <el-option v-for="item in tagNameList" :key="item.value" :label="item.label" :value="item.value">
              <span>{{ item.label }} {{ ' | ' + item.unit }} {{ ' | ' + item.desc }}</span>
            </el-option>
            <el-pagination small @current-change="selecthandlePageChange" :current-page="currentPage"
              :page-size="pageSize" :total="filteredOptions.length" layout="prev, pager, next">
            </el-pagination>
          </el-select>
          <el-icon v-if="index === pointsList.length - 1" size="20" style="padding:0px 10px; cursor: pointer"
            @click="addpointsFun">
            <CirclePlusFilled />
          </el-icon>
          <el-icon v-else size="20" style="padding:0px 10px; cursor: pointer" @click="removeFormulaTag(index)">
            <RemoveFilled />
          </el-icon>
        </el-form-item>
        <el-form-item label="Description">
          <el-input v-model="addPresetForm.description" style="width: 800px" :rows="4" type="textarea"
            placeholder="Please input" />
        </el-form-item>
      </el-form>
      <span class="dialog-footer">
        <el-button @click="presetFormVisible = false">Cancel</el-button>
        <el-button type="primary" @click="SubAddPreseForm">Submit</el-button>
      </span>

    </el-dialog>
  </div>
</template>


<script>
import KEYCODE_DIR_MAP from '@/config/keyCodeMap'
import { computed, nextTick, onBeforeUnmount, onMounted, reactive, ref, toRaw, toRefs, watchEffect } from "vue";
import ImgTextDialog from '@/components/ImgTextDialog'
import * as d3 from "d3";
import CustomCard from "@/components/CustomCard.vue";
import ScrollModel from "@/components/ScrollModel.vue";
import Trendtag from "@/components/trendtag.vue";
import Trendpad from "@/components/trendpad.vue";
import FormulaDialog from '@/components/FormulaDialog'
import { CirclePlusFilled, RemoveFilled } from "@element-plus/icons-vue";
import {
  copyWell,
  downloadFile,
  editConfig,
  exportWellHistory,
  getConfig,
  getImageUrl,
  getTagType,
  getWellRealData,
  getWellTag,
  queryList,
  queryWellHistory,
  uploadFile,
  getWellInfoProductionLast,
  getFavoriteList,
  deleteFavorite,
  formulaManageList,
  addOrUpdate,
  wellManageGetAll,
  formulaManageDelete,
  getFormulaDrop,
  getPadDrop,
  getAllWellTag
} from "@/api/index";
import { getWellDrop } from "@/api/steam"
import { ElLoading, ElMessage, ElMessageBox } from "element-plus";
import { exportFile, formatNumber, getParameterFromUrl, lowerBounding } from "@/utils/common";
import { useRoute, useRouter } from "vue-router";
import { tagConfigs } from "@/config/tagTypeConfig";
import { addConfig } from "@/api";
import useHtmlToImage from "@/hooks/useHtmlToImage";
import { COMMON_CONFIG, ICON_COMPONENTS, RIGHT_PROPS, RIGHT_SETTING, TEXTUAL_DATA, PICTURE_SUMMARY } from '@/config/D3DrawConfiguration'
import { dragResizeClose, dragResizeInit, dragResizeOpen, generateRandomKey } from '@/utils/dragresize'
import CryptoJS from 'crypto-js';
import LeftComponents from './components/LeftComponents/index.vue';

export default {
  name: "D3Draw",
  components: {
    CustomCard,
    FormulaDialog,
    ScrollModel,
    Trendtag,
    Trendpad,
    ImgTextDialog,
    LeftComponents
  },
  setup: () => {
    const route = useRoute();
    const router = useRouter();
    const SECRET_KEY = 'a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6c7b8c9d0e1f2a3b4c5d6a7b8';
    let svg = reactive({});
    const formRef = ref(null)
    const imgTextDialogVisible = ref(false)
    const imgTextDialogParams = reactive({})
    const canvasSizeBase = {
      width: 0,
      height: 0
    }
    let canvasSizeConfig = ref({
      type: 'canvasSizeSetting',
      keyType: 0,
      width: 100,
      height: 100
    })
    const contextMenu = reactive({
      visible: false,
      left: 0,
      top: 0,
      zIndex: 0,
      target: null
    })
    // eslint-disable-next-line
    let g = reactive({});

    let state = reactive({
      tagsName: '',
      StoragePages: [
        { img: require("@/assets/circ.png"), remark: 'CIRC Well' },
        { img: require("@/assets/Prod  Well.png"), remark: 'Prod  Well' },
        { img: require("@/assets/NCG Well.png"), remark: 'NCG Well' },
        { img: require("@/assets/INF Well.png"), remark: 'INF Well' },
      ],
      AdIndex: "",
      rightCardCollapsed: true,
      presePadValue: '',
      presetWell: '',
      bindingList: TEXTUAL_DATA,
      PicturesAreData: PICTURE_SUMMARY,
      preseOptionsOne: [],
      preseOptionsTwo: [],
      optionsTwo: [],
      optionsOne: [],
      uuindValue: [],
      productionid: [],
      espname: '',
      selectedValue: '',
      padValue: '',
      setValueData: [],
      isEditting: false,
      wellTestStatus: false,
      importWellDialogVisible: false,
      list: [],
      originWellId: "",
      imgMsg: "",
      previewSrcList: [],
      wellName: "",
      isredrill: "",
      wellnameid: "",
      wellidNum: "",
      hoverData: false,
      tooltipX: 0,
      tooltipY: 0,
      activeTooltip: null,
      detailData: {
        otherItems: [],
        configJson: [],
        imageUrl: "",
        id: "",
        wellId: getParameterFromUrl("wellId")
      },
      wellData: {},
      btmTableData: [],
      configs: [],
      tagsList: [],
      formulaList: [],
      tagTypesList: [],
      curIndex: 0,
      rightCardVisable: false,
      dialogVisible: false,
      rightCard: [],
      rightProps: RIGHT_PROPS,
      data: {},
      otherWellTagList: [],
      form: {
        otherWellId: '',
        keyType: 0,
        key: "",
        x: 0,
        y: 0,
        width: 0,
        height: 0,
        valueColor: "#ffffff",
        remark: "",
        unit: "",
        desc: "",
        formulaName: "",
        formulaText: "",
        valueFontSize: "14"
      },
      formulaTag: {
        t0: ""
      },
      iconComponents: ICON_COMPONENTS,
      commednumber: "",
      scrollModelData: [],
      isTrendtag: false,
      isTrendpad: false,
      tagName: "",
      tagNameList: [],
      tagTitle: "",
      handletitle: "",
      tagType: "",
      unit: "",
      keyType: "",
      storagekey: "",
      storagekeytype: "",
      selectedTextIds: [],
      isUser: false,
      favoriteDialogVisible: false,
      favoritaList: [],
      existingWindow: { closed: true },
      presetFormulasVisible: false,
      presetFormulasList: [],
      presetNum: 1,
      presetSize: 10,
      presetTotal: 0,
      presetWellList: [],
      isPreseEdit: false,
      preseId: '',
      addPresetForm: {},
      rules: {
        wellId: [
          { required: true, message: 'Please input WellId', trigger: 'blur' },
        ],
        formulaName: [
          { required: true, message: 'Please input FormulaName', trigger: 'blur' },
        ],
        formulaText: [
          { required: true, message: 'Please input FormulaText', trigger: 'blur' },
        ],
      },
      presetFormVisible: false,
      pointsList: [{ name: 't0', tagName: '' }],
      apiTagsList: [],
      filteredOptions: [],
      currentPage: 1,
      pageSize: 10,

    });
    const wellTestStatusFlag = computed(() => {
      return state.wellTestStatus ? "ON" : "OFF";
    });
    const wellTestStatusFlagColor = computed(() => {
      return state.wellTestStatus ? "#00b625" : "#e1323b";
    });
    const getFormulaDropList = async wellId => {
      getFormulaDrop({ wellId: wellId }).then(res => {
        if (res?.code === 200) {
          state.formulaList = res.data || [];
        }
      })
    }
    const changelist = () => {
      ground();
    }
    const handleRemoteMethod = (query) => {
      if (query !== "") {
        setTimeout(() => {
          state.filteredOptions = state.apiTagsList.filter((item) =>
            item.label.toLowerCase().includes(query.toLowerCase())
          );
          state.currentPage = 1; // Reset to first page
          updatePaginatedOptions();
        }, 200);
      } else {
        state.filteredOptions = state.apiTagsList;
        state.currentPage = 1; // Reset to first page
        updatePaginatedOptions();
      }
    }
    const ground = () => {
      getAllWellTag().then((res) => {
        if (res.code === 200) {
          const uniqueTags = new Set();
          state.apiTagsList = res.data
            .filter((item) => {
              const tagName = item.tagName;
              if (!uniqueTags.has(tagName)) {
                uniqueTags.add(tagName);
                return true;
              }
              return false;
            })
            .map((item) => ({
              label: item.tagName,
              value: item.tagName,
              desc: item.remark,
              unit: item.unit
            }));
          state.filteredOptions = state.apiTagsList;
          state.currentPage = 1;
          updatePaginatedOptions();
        }
      });
    }
    const selecthandlePageChange = (page) => {
      state.currentPage = page;
      updatePaginatedOptions();
    }
    const updatePaginatedOptions = () => {
      const start = (state.currentPage - 1) * state.pageSize;
      const end = state.currentPage * state.pageSize;
      state.tagNameList = state.filteredOptions.slice(start, end);
    }
    const presePadChange = async () => {
      let params = {
        padId: state.presePadValue,
        type: 1,
      };
      await getWellDrop(params).then(res => {
        if (res.code == 200) {
          state.preseOptionsTwo = res.data;
        } else {
          ElMessage.error(res.msg);
        }
      })
    }
    const getPadList = async () => {
      await getPadDrop().then(res => {
        if (res.code == 200) {
          state.optionsOne = res.data.map((item) => ({ ...item }));
          if (state.optionsOne.length != 0) {
            state.padValue = route.query.padId
            singleWell();
          }

        }
      })
    }
    const singleWell = async () => {
      let params = {
        padId: state.padValue,
        type: 1,
      };
      await getWellDrop(params).then(res => {
        if (res.code == 200) {
          state.optionsTwo = res.data;
        } else {
          ElMessage.error(res.msg);
        }
      })
    }
    //井下拉列表
    const wellManageGetAllList = () => {
      wellManageGetAll().then(res => {
        if (res.code == 200) {
          state.presetWellList = res.data
        }
      })
    }
    //公式列表分页
    const handlePageChange = (page) => {
      state.presetNum = page;
      presetFormulas();
    }
    //默认打开查询
    const presetFormulas = () => {
      state.presePadValue = state.padValue
      state.presetWell = state.selectedValue
      presePadChange()
      wellManageGetAllList()
      getFormulaManageList()
      state.presetFormulasVisible = true
    }
    //查询数据
    const getFormulaManageList = () => {
      formulaManageList({ page: state.presetNum, pageSize: state.presetSize, wellId: state.presetWell }).then(res => {
        if (res.code == 200) {
          state.presetFormulasList = res.data.records;
          state.presetTotal = res.data.total
        }
      });
    }
    //删除公式列表
    const formulaManageDeleteFun = (e) => {
      ElMessageBox.confirm(
        'Delete this preference?',
        'Delete',
        {
          confirmButtonText: 'OK',
          cancelButtonText: 'Cancel',
          type: 'warning',
        }
      )
        .then(() => {
          formulaManageDelete([e.id]).then(res => {
            if (res.code == 200) {
              getFormulaManageList()
              ElMessage.success(res.msg);
            } else {
              ElMessage.warning(res.msg);
            }
          })
        })

    }

    //添加列表
    const addPreseFormFun = () => {
      state.isPreseEdit = false
      state.presetFormVisible = true
      state.pointsList = [{ name: 't0', tagName: '' }]
      state.addPresetForm = {}
      state.addPresetForm.wellId = state.presetWell

    }
    //编辑列表
    const editPreseIdClick = (e) => {
      state.isPreseEdit = true
      state.presetFormVisible = true
      state.preseId = e.id
      state.addPresetForm.formulaName = e.formulaName
      state.addPresetForm.formulaText = e.formulaText
      state.addPresetForm.description = e.description
      state.addPresetForm.wellId = e.wellId
      // 去掉大括号并分割字符串
      const items = e.formulaTags.slice(1, -1).split(',');
      // 创建一个数组来存储结果对象
      state.pointsList = []

      // 遍历每个键值对
      items.forEach(item => {
        // 分割键和值
        const [key, value] = item.split('=');
        // 创建对象并添加到结果数组
        state.pointsList.push({
          name: key,
          tagName: value
        });
      });

    }
    const toggleRightCard = () => {
      state.rightCardCollapsed = !state.rightCardCollapsed;
      if (state.rightCardCollapsed == false) {
        const canvas = d3.select('#svg')
        const oldWidth = canvasSizeBase.width
        canvasSizeConfig.value.width = canvasSizeConfig.value.width + 10
        canvas
          .attr('width', oldWidth * canvasSizeConfig.value.width / 100)
      } else {
        const canvas = d3.select('#svg')
        const oldWidth = canvasSizeBase.width
        canvasSizeConfig.value.width = canvasSizeConfig.value.width - 10
        canvas
          .attr('width', oldWidth * canvasSizeConfig.value.width / 100)
      }
    };
    //添加公式
    const addpointsFun = () => {
      const maxAttempts = 10;
      let tagNames = []
      state.pointsList.forEach(v => {
        tagNames.push(v.name)
      })
      for (let i = 0; i < maxAttempts; i++) {
        if (!tagNames.includes(`t${i}`)) {
          state.pointsList.push({ name: `t${i}`, tagName: '' });
          break;
        }
      }
    };
    //删除公式
    const removeFormulaTag = (index) => {
      state.pointsList.splice(index, 1)
    };

    //保存添加公式
    const SubAddPreseForm = () => {
      formRef.value.validate((valid) => {
        if (valid) {
          let str = '{'
          state.pointsList.forEach((v, i) => {
            if (i == state.pointsList.length - 1) {
              str = str + v.name + '=' + v.tagName + '}'
            } else {
              str = str + v.name + '=' + v.tagName + ','
            }
          })
          let obj
          if (state.isPreseEdit) {
            //编辑
            obj = {
              "formulaName": state.addPresetForm.formulaName,
              "formulaText": btoa(state.addPresetForm.formulaText),
              "description": state.addPresetForm.description,
              "wellId": state.addPresetForm.wellId,
              "id": state.preseId,
              "formulaTags": str
            }

          } else {
            //保存
            obj = {
              "formulaName": state.addPresetForm.formulaName,
              "formulaText": btoa(state.addPresetForm.formulaText),
              "description": state.addPresetForm.description,
              "wellId": state.addPresetForm.wellId,
              "formulaTags": str
            }
          }
          addOrUpdate(obj).then(res => {
            if (res.code == 200) {
              ElMessage.success(res.msg);
              state.presetFormVisible = false
              state.pointsList = [{ name: 't0', tagName: '' }]
              state.addPresetForm = {}
              getFormulaManageList()
            } else {
              ElMessage.warning(res.msg);
            }
          })
        }
      });

    };

    const getSvg = () => {
      return svg;
    }

    const init = () => {
      // 获取父节点
      const parentNode = document.getElementById("d3CanvasView");
      if (!parentNode) {
        console.error("父节点不存在");
        return;
      }
      svg = initD3Canvas();

    };
    //打开喜好列表
    const openFavoriteList = () => {
      state.favoriteDialogVisible = true
      getFavoriteList().then(res => {
        state.favoritaList = res.data
      })
    }

    //删除喜好
    const deleteClick = (e) => {
      ElMessageBox.confirm(
        'Delete this preference?',
        'Delete',
        {
          confirmButtonText: 'OK',
          cancelButtonText: 'Cancel',
          type: 'warning',
        }
      )
        .then(() => {
          deleteFavorite([e.row.id]).then(res => {
            if (res.code == 200) {
              openFavoriteList()
            }
          })
        })
    }


    const rowDbclickFun = (e) => {
      localStorage.setItem('preferenceId', e.id)
      localStorage.setItem('preferenceName', e.name)
      openOrFocusTabPreferencelike('trendTab')
      state.favoriteDialogVisible = false
    }
    function openOrFocusTabPreferencelike(tabName) {
      const queryParams = {
        wellName: state.wellName,
        wellId: route.query.wellId,
      }
      const encryptedData = CryptoJS.AES.encrypt(
        JSON.stringify(queryParams),
        SECRET_KEY
      ).toString();
      const target = router.resolve({
        name: 'TrendCanPreference',
        query: { data: encryptedData },
      })
      // 尝试获取已经打开的窗口
      state.existingWindow = window.open('', tabName, 'width=1500,height=800,location=no');
      // 如果窗口存在但没有关闭，则重新激活该窗口
      if (state.existingWindow && !state.existingWindow.closed) {
        state.existingWindow.location.href = target.href; // 改变现有窗口的URL
        // existingWindow.focus(); // 将焦点切换到该窗口
        window.open('javascript:;', tabName)
      } else {
        // 如果窗口不存在或已经关闭，则打开一个新窗口
        window.open(target.href, tabName);
      }
    }
    const canvasSizeChange = () => {
      const canvas = d3.select('#svg')
      const oldWidth = canvasSizeBase.width
      const oldHeight = canvasSizeBase.height
      console.log(canvasSizeConfig.value.width, 'canvas-----------')
      canvas
        .attr('width', oldWidth * canvasSizeConfig.value.width / 100)
        .attr('height', oldHeight * canvasSizeConfig.value.height / 100)
    }
    const zLevelChange = () => {
      const child = d3.select('#svg').selectAll('image')
      const elemSortArr = []
      child['_groups'][0].forEach(item => {
        elemSortArr.push({
          id: item.getAttribute('id'),
          index: item.getAttribute('index')
        })
      })
      elemSortArr.sort((a, b) => Number(a.index) - Number(b.index))
      const insertIndex = lowerBounding(elemSortArr.map(item => item.index), contextMenu.zIndex)
      // 获取列表和列表项
      let list = document.getElementById('svg');
      let curr = document.getElementById(contextMenu.target);
      let anchor = document.getElementById(elemSortArr[insertIndex === elemSortArr.length ? insertIndex - 1 : insertIndex].id).nextSibling;

      list.insertBefore(curr, anchor);
      d3.select(`#${contextMenu.target}`).attr('index', contextMenu.zIndex)
      contextMenu.visible = false
    }
    const ProductionLast = async wellId => {
      let formData = new FormData();
      formData.append("wellId", wellId);
      getWellInfoProductionLast(formData).then(res => {
        if (res.code == 200) {
          state.productionid = res.data.lastInfoList;
        }
      });
    }
    const changeTag = ({ form, formulaTag, ...descDateil }) => {
      state.formulaTag = formulaTag
      state.dialogVisible = false;
      const { desc, unit } = descDateil;
      // todo 需要判断text和svg的类型
      const currSvgElem = d3.select(`#${form.id}`)
      if (form.keyType.toString() === '0'
        && document.getElementById(form.id).tagName === 'text'
      ) {
        currSvgElem.text(form.remark)
      }
      currSvgElem
        .attr("x", form.x)
        .attr("y", form.y)
        .attr("width", form.width)
        .attr("height", form.height)
        .attr("data-keyType", form.keyType)
        .attr("data-key", form.key)
        .attr("data-unit", unit)
        .attr("data-desc", desc)
        .attr("data-valueColor", form.valueColor)
        .attr("data-valueFontSize", form.valueFontSize)
        .attr("data-remark", form.remark)
        .style("width", form.width + "px")
        .style("height", form.height + "px");

      d3.select(`#${form.id}foreignObject`)
        .attr("x", form.x)
        .attr("y", form.y)
        .attr("width", form.width)
        .attr("height", form.height)
        .attr("data-keyType", form.keyType)
        .attr("data-key", form.key)
        .attr("data-unit", unit)
        .attr("data-desc", desc)
        .attr("data-valueColor", form.valueColor)
        .attr("data-valueFontSize", form.valueFontSize)
        .attr("data-remark", form.remark);

      if (form.keyType === "3") {
        d3.select(`#${form.id}`)
          //点击改了的保存本地的。
          // .attr("data-formulaName", form.id)
          .attr("data-formulaName", form.id)
          .attr("data-formulaId", form.formulaId)
        // .attr("data-formulaText", form.formulaText)
        // .attr("data-formulaTag", JSON.stringify(state.formulaTag));
        d3.select(`#${form.id}foreignObject`)
          // .attr("data-formulaName", form.id)
          .attr("data-formulaName", form.id)
          .attr("data-formulaId", form.formulaId)
        // .attr("data-formulaText", form.formulaText)
        // .attr("data-formulaTag", JSON.stringify(state.formulaTag));
      }
      if (form.keyType === "4") {
        d3.select(`#${form.id}`)
          .attr('tag-well-id', form.otherWellId)
        d3.select(`#${form.id}foreignObject`)
          .attr('tag-well-id', form.otherWellId)
      }
      state.storagekey = form.key;
      state.storagekeytype = form.keyType;
    };
    const updateJson = params => {
      state.btmTableData = params;
    };
    const setCard = params => {
      state.rightCard = JSON.parse(JSON.stringify(params));
    };

    let isMouseDown = false
    const mouseStart = { x: 0, y: 0 }
    let moveDirection
    const initD3Canvas = (customWidth, customHeight) => {
      const parentNode = document.getElementById("d3Canvas");
      canvasSizeBase.width = parentNode.clientWidth
      canvasSizeBase.height = parentNode.clientHeight
      const d3Canvas = d3
        .select("#d3Canvas")
        .append("svg")
        .attr("id", "svg")
        .attr("width", canvasSizeBase.width)
        .attr("height", canvasSizeBase.height)
        .on('mousedown', svgMouseDown)
        .on('mousemove', svgMouseMove)
        .on('mouseup', svgMouseUp);
      g = d3Canvas;
      COMMON_CONFIG.initRation(canvasSizeBase.width, canvasSizeBase.height)
      return d3Canvas;
    };
    const formatMouseEventPosition = (e) => {
      const tagName = e.target.tagName.toLowerCase()
      let x, y
      if (tagName === 'input') {
        const boundingRect = e.target.parentNode.getBoundingClientRect()
        const scrollRect = document.getElementById('d3Canvas')
        x = boundingRect.left + e.offsetX + parseInt(scrollRect.scrollLeft)
        y = boundingRect.top - boundingRect.height + e.offsetY + parseInt(scrollRect.scrollTop)
      } else {
        x = e.offsetX
        y = e.offsetY
      }
      return { x, y }
    }
    const svgMouseDown = (e) => {
      isMouseDown = (e.buttons === 1 && state.isEditting)
      const targetClassName = e.target.getAttribute('class')
      if (targetClassName !== 'copy-move-group-outline') {
        d3.selectAll('.copy-move-group-outline').remove()
        d3.selectAll('.copy-move-group-item')
          .attr('class', function () {
            return d3.select(this).attr('class').replace('copy-move-group-item', '')
          })
      }
      if (e.shiftKey && isMouseDown) {
        const { x, y } = formatMouseEventPosition(e)
        mouseStart.x = x
        mouseStart.y = y
        g.append('rect')
          .attr('class', 'copy-move-group-outline')
          .attr('x', mouseStart.x)
          .attr('y', mouseStart.y)
          .style('fill', 'rgba(255,255,255,0.1)')
          .style('stroke-width', '0.5px') // 设置边框宽度
          .style('stroke', '#4e6ef2')
          .on("contextmenu", function (event) {
            if (!state.isEditting) return false
            event.preventDefault();
            contextMenu.visible = false
            if (d3.selectAll('.copy-move-group-item')['_groups'][0][0]) {
              ElMessageBox.confirm(
                'Delete all selected components?',
                'Delete',
                {
                  confirmButtonText: 'OK',
                  cancelButtonText: 'Cancel',
                  type: 'warning',
                }
              )
                .then(() => {
                  d3.select('.copy-move-group-outline').remove()
                  d3.selectAll('.copy-move-group-item').remove()
                })
            } else {
              d3.select('.copy-move-group-outline').remove()
            }
          })
      }
    }
    const svgMouseUp = () => {
      if (isMouseDown) {
        document.removeEventListener('keydown', svgKeyDown);
        document.addEventListener('keydown', svgKeyDown);
        d3.select('.copy-move-group-outline')
          .style('cursor', 'move')
          .call(d3.drag()
            .on("drag", copyGroupMove)
          )
        isMouseDown = false
      }
    }
    const svgMouseMove = (e) => {
      if (!isMouseDown) return false
      if (e.shiftKey) {
        requestAnimationFrame(() => {
          const copyMoveGroupSelection = d3.select('.copy-move-group-outline')
          const { x: offsetX, y: offsetY } = formatMouseEventPosition(e)
          const width = offsetX - mouseStart.x
          const height = offsetY - mouseStart.y
          if (width < 0) {
            copyMoveGroupSelection
              .attr('width', -width)
              .attr('x', offsetX)
          } else {
            copyMoveGroupSelection
              .attr('width', width)
          }
          if (height < 0) {
            copyMoveGroupSelection
              .attr('height', -height)
              .attr('y', offsetY)
          } else {
            copyMoveGroupSelection
              .attr('height', height)
          }
        })

      }
    }
    const svgKeyDown = e => {
      const keyCode = e.keyCode.toString()
      if (e.shiftKey && Object.keys(KEYCODE_DIR_MAP).includes(keyCode)) {
        moveDirection = KEYCODE_DIR_MAP[keyCode].direction
        findAllSvgInSelection(KEYCODE_DIR_MAP[keyCode].isClone)
      }
    }
    const copyGroupMove = (e) => {
      [d3.select('.copy-move-group-outline'), d3.selectAll('.copy-move-group-item')].forEach(item => {
        item
          .attr('x', function () {
            let x = +d3.select(this).attr("x")
            return ['free', 'horizontal'].includes(moveDirection) ? x + e.dx : x
          })
          .attr('y', function () {
            let y = +d3.select(this).attr("y")
            return ['free', 'vertical'].includes(moveDirection) ? y + e.dy : y
          })
      })
    }
    const findAllSvgInSelection = (cloneCurr = true) => {
      const copyMoveGroupSelection = d3.select('.copy-move-group-outline')
      const selection = {
        xStart: +copyMoveGroupSelection.attr('x'),
        yStart: +copyMoveGroupSelection.attr('y'),
        xEnd: +copyMoveGroupSelection.attr('x') + (+copyMoveGroupSelection.attr('width')),
        yEnd: +copyMoveGroupSelection.attr('y') + (+copyMoveGroupSelection.attr('height'))
      }
      d3.selectAll('.copy-move-group-item')
        .attr('class', function () {
          return d3.select(this).attr('class').replace('copy-move-group-item', '')
        })
      cloneSvgInSelection(cloneCurr, selection)
      document.addEventListener('keydown', null);
    }
    const isInSelection = (x, y, selection) => {
      return x >= selection.xStart && x <= selection.xEnd && y >= selection.yStart && y <= selection.yEnd
    }
    const cloneSvgInSelection = (cloneCurr, selection) => {
      d3.selectAll('#svg').selectAll('*')['_groups'][0].forEach(item => {
        if (item.getAttribute('class') && item.getAttribute('class').indexOf('copy-move-group-outline') === -1) {
          const x = +item.getAttribute('x'), y = +item.getAttribute('y')
          if (isInSelection(x, y, selection)) {
            const target = d3.select(`#${item.id}`)
            const output = cloneCurr ? target.clone(true) : target
            const child = output.select('input')
            output.attr('class', `${output.attr('class')} copy-move-group-item`)
            if (cloneCurr) {
              const randomKey = generateRandomKey(18)
              output.attr('id', `${item.id}-${randomKey}`)
              const dataId = output.attr('data-id') || undefined
              output.attr('data-id', dataId ? dataId + '-' + randomKey : dataId)
            }
            if (child['_groups'][0][0]) {
              child.attr('class', `${child.attr('class')} copy-move-group-item`)
              if (cloneCurr) {
                const randomKey = generateRandomKey(18)
                const childId = child.attr('id')
                const childDataID = child.attr('data-id') || undefined
                child
                  .attr('id', childId + '-' + randomKey)
                  .attr('data-id', childDataID ? childDataID + '-' + randomKey : childDataID)
              }
            }
          }
        }
      })
    }

    const handleData = data => {
      state.handletitle = data;
    };
    //添加局部网格背景
    const createGridBackground = (gridSize = 20) => {
      g.insert("rect", ":first-child")
        .attr("width", "100%")
        .attr("height", "100%")
        .attr("fill", "url(#grid)");

      // 使用网格样式填充 SVG 元素背景
      const pattern = svg
        .insert("defs", ":first-child")
        .append("pattern")
        .attr("id", "grid")
        .attr("width", gridSize)
        .attr("height", gridSize)
        .attr("patternUnits", "userSpaceOnUse");

      // 添加网格线
      pattern
        .append("path")
        .attr("d", `M ${gridSize} 0 L 0 0 0 ${gridSize}`)
        .attr("stroke", "lightgray")
        .attr("stroke-width", 0.5)
        .attr("fill", "none");
    };
    //绘制圆形
    const bindClickEvent = (element, dataItem) => {
      element.on("click", () => {
        handleTagClick(dataItem);
      });
      element.on("mouseover", (event) => {
        if (!state.isEditting) {
          state.activeTooltip = dataItem;
          state.tooltipX = event.pageX + 10;
          state.tooltipY = event.pageY + 10;
          state.hoverData = true;
        }
      });
      element.on("mouseout", () => {
        state.hoverData = false;
      });
    };
    const findValueByKey = (key, data) => {
      const item = data.find(item => item.key === key);
      return item ? item.value : null;
    };
    const getTagByKeyType = val => {
      handleTagClick(val);
    };


    const handleMouseEnter = val => {
      const { dataItem, event } = val;
      if (!state.isEditting) {
        state.activeTooltip = dataItem;
        state.tooltipX = event.pageX + 10;
        state.tooltipY = event.pageY + 10;
      }
      state.hoverData = !state.isEditting
    };

    const handleMouseOut = () => {
      state.hoverData = false;
    }

    function openOrFocusTab(tabName, tag) {
      const target = router.resolve({
        name: 'TrendComparison',
        query: {
          key: tag.key,
          wellName: state.wellName

        }
      })
      // 尝试获取已经打开的窗口
      var existingWindow = window.open('', tabName, 'width=800,height=600');
      // 如果窗口存在但没有关闭，则重新激活该窗口
      if (existingWindow && !existingWindow.closed) {
        existingWindow.location.href = target.href; // 改变现有窗口的URL
        // existingWindow.focus(); // 将焦点切换到该窗口
        window.open('javascript:;', tabName)
      } else {
        // 如果窗口不存在或已经关闭，则打开一个新窗口
        window.open(target.href, tabName);
      }
    }
    function openOrFocusTabCnBeStored(tabName, tag) {
      const target = router.resolve({
        name: 'TrendCanBeStored',
        query: {
          key: tag.key,
          wellName: state.wellName,
          wellId: route.query.wellId
        }
      })
      // 尝试获取已经打开的窗口
      var existingWindow = window.open('', tabName, 'width=1000,height=800');
      // 如果窗口存在但没有关闭，则重新激活该窗口
      if (existingWindow && !existingWindow.closed) {
        existingWindow.location.href = target.href; // 改变现有窗口的URL
        // existingWindow.focus(); // 将焦点切换到该窗口
        window.open('javascript:;', tabName)
      } else {
        // 如果窗口不存在或已经关闭，则打开一个新窗口
        window.open(target.href, tabName);
      }
    }
    function openOrFocusTabPreference(tabName, tag) {
      // AES 加密
      const queryParams = {
        key: tag.key,
        unit: tag.unit,
        desc: tag.desc,
        wellName: state.wellName,
      }

      const encryptedData = CryptoJS.AES.encrypt(
        JSON.stringify(queryParams),
        SECRET_KEY
      ).toString();
      const target = router.resolve({
        name: 'TrendCanPreference',
        query: { data: encryptedData },
      })

      if (state.existingWindow.closed) {
        localStorage.removeItem('dataList');
        localStorage.removeItem('legend');
        localStorage.removeItem('wellName');
        localStorage.removeItem('preferenceId');
        localStorage.removeItem('preferenceName');
        localStorage.removeItem('unitList');
      }
      // 尝试获取已经打开的窗口
      state.existingWindow = window.open('javascript:;', tabName, 'width=1500,height=800');

      // 如果窗口存在但没有关闭，则重新激活该窗口
      if (state.existingWindow && !state.existingWindow.closed) {
        state.existingWindow.location.href = target.href; // 改变现有窗口的URL
        // existingWindow.focus(); // 将焦点切换到该窗口
        // window.open('javascript:;', tabName)
      } else {
        // 如果窗口不存在或已经关闭，则打开一个新窗口
        window.open(target.href, tabName);
      }
    }


    const handleTagClick = tag => {
      // if (state.isUser) {
      //   openOrFocusTabCnBeStored('trendTab', tag)
      // } else {
      //   openOrFocusTab('trendTab', tag)
      // }

      openOrFocusTabPreference('trendTab', tag)
      state.keyType = tag.keyType || tag.keytype;
      if (state.keyType === "2") {
        state.tagName = tag.key;
        state.handletitle = tag.key
        // const tagInfo = tagConfigs[tag.key];
        // if (tagInfo) {
        //   ['tagName', 'tagTitle', 'unit'].forEach(k => {
        //     state[k] = tagInfo[k]
        //   })
        // }
      } else if (state.keyType === "1") {
        state.tagType = tag.key;
        if (tag.remark === "") {
          tag.remark = findValueByKey(state.tagType, state.tagTypesList);
        }
        state.tagName = tag.remark;
        state.tagTitle = tag.remark;
        state.unit = tag.unit;
      } else if (state.keyType === '4') {
        state.tagName = tag.key;
      }
      // state.isTrendtag = true;
      state.handletitle = '';
    };
    const unBindClickEvent = element => {
      element.on("click", null);
      state.isTrendtag = false;
    };
    //画图片
    const drawPoints = (data = []) => {
      let rightProps = [];
      data.sort((a, b) => {
        return a.index - b.index
      })

      const containerDom = document.getElementById('svg');
      let set_a = JSON.parse(JSON.stringify(state.productionid))
      for (let i = 0; i < data.length; i++) {
        if (!data[i].type) continue
        let a = null;
        data[i].x = COMMON_CONFIG.getShowRowVal(containerDom.clientWidth, data[i].x)
        data[i].y = COMMON_CONFIG.getShowColVal(containerDom.clientHeight, data[i].y)
        data[i].width = COMMON_CONFIG.getShowRowVal(containerDom.clientWidth, data[i].width)
        data[i].height = COMMON_CONFIG.getShowColVal(containerDom.clientHeight, data[i].height)
        data[i].valueFontSize = COMMON_CONFIG.getShowRowVal(containerDom.clientWidth, data[i].valueFontSize || 12)
        if (data[i].type === "line") {
          a = g
            .append("line")
            .attr("x1", data[i].x)
            .attr("y1", data[i].y)
            .attr("x2", data[i].x + data[i].width)
            .attr("y2", data[i].y + data[i].height)
            .attr("stroke-width", 2)
            .attr("stroke", data[i].valueColor)
            .attr("data-type", data[i].type)
            .attr("width", data[i].width)
            .attr("height", data[i].height);

        } else if (data[i].type === "input") {
          a = g
            .append("foreignObject")
            .attr("x", data[i].x)
            .attr("id", data[i].id + "foreignObject")
            .attr("y", data[i].y)
            .attr("data-id", data[i].id)
            .attr("width", +data[i].width + 10)
            .attr("height", +data[i].height + 10)
            .attr("data-keyType", data[i].keyType)
            .attr("data-key", data[i].key)
          const inner = a.append("xhtml:input")
            .attr("id", data[i].id)
            .attr("value", data[i].value || "")
            .attr("data-type", "text")
            .attr("data-id", data[i].id)
            .attr("data-pid", data[i].pid)
            .attr("data-keyType", data[i].keyType)
            .attr("data-key", data[i].key)
            .attr("data-unit", data[i].unit)
            .attr("data-desc", data[i].desc)
            .attr("data-valueColor", data[i].valueColor)
            .attr("data-valueFontSize", data[i].valueFontSize)
            .attr("data-className", data[i].className)
            .attr("data-remark", data[i].remark)
            .attr("class", data[i].className)
            .attr("autocomplete", 'off')
            .style("color", data[i].valueColor)
            .style("width", data[i].width + "px")
            .style("height", data[i].height + "px")
            .style("font-size", data[i].valueFontSize + "px");
          if (data[i].keyType.toString() === '3') {
            //应该是回显用的1---------
            // a.attr("data-formulaTag", JSON.stringify(data[i].formula.formulaTag))
            //   .attr("data-formulaName", data[i].formula.formulaName)
            //   .attr("data-formulaText", data[i].formula.formulaText)
            //   .attr("data-valueFontSize", data[i].valueFontSize + 'px');

            a.attr("data-formulaName", data[i].formula.elementId)
              .attr("data-formulaId", data[i]?.formula?.formulaId)
              .attr("data-valueFontSize", data[i].valueFontSize + 'px');
            inner.attr("data-formulaName", data[i]?.formula?.elementId)
              .attr("data-formulaId", data[i]?.formula?.formulaId)

            // inner.attr("data-formulaTag", JSON.stringify(data[i].formula.formulaTag))
            //   .attr("data-formulaName", data[i].formula.formulaName)
            //   .attr("data-formulaText", data[i].formula.formulaText)

          } else {
            a.attr('tag-well-id', data[i].tagWellId)
            inner.attr('tag-well-id', data[i].tagWellId)
          }
        } else if (data[i].type === "rightcard") {
          set_a.forEach(item => {
            if (item.tagName == data[i].key) {
              data[i].lastTime = item.lastTime
            }
          })
          rightProps.push(data[i]);
        } else if (data[i].type === "text") {
          a = g
            .append("text")
            .attr("x", data[i].x)
            .attr("y", data[i].y)
            .attr("id", data[i].id)
            .attr("width", +data[i].width + 10)
            .attr("height", +data[i].height + 10)
            // .text(data[i].remark || "")
            .text(data[i].remark || "")
            .attr("data-type", "text")
            .attr("data-id", data[i].id)
            .attr("data-pid", data[i].pid)
            .attr("data-keyType", data[i].keyType)
            .attr("data-key", data[i].key)
            .attr("data-unit", data[i].unit)
            .attr("data-desc", data[i].desc)
            .attr("data-valueColor", data[i].valueColor)
            .attr("data-valueFontSize", data[i].valueFontSize)
            .attr("data-className", data[i].className)
            .attr("data-remark", data[i].remark)
            .style("fill", data[i].valueColor)
            .style("font-size", data[i].valueFontSize)
            .attr("class", data[i].className)
          if (data[i].keyType.toString() === '3') {
            //应该是回显用的2--------
            a.attr("data-formulaTag", data[i]?.formula?.formulaTag ? JSON.stringify(data[i].formula.formulaTag) : '')
              .attr("data-formulaName", data[i]?.formula?.formulaName)
              .attr("data-formulaText", data[i]?.formula?.formulaText)
          }
        } else if (data[i].type === "png" || data[i].belongToImage === 'true') {
          if (data[i].imageUrl) {
            const img = new Image();
            img.src = require(`@/assets/${data[i].imageUrl}`)
            a = g.append('image')
              .attr('xlink:href', img.src)
              .attr('preserveAspectRatio', 'none')
              .attr("x", +data[i].x)
              .attr("y", +data[i].y)
              .attr("imageUrl", data[i].imageUrl)
              .attr("id", data[i].id)
              .attr("width", +data[i].width)
              .attr("height", +data[i].height)
              .attr("text", data[i].text || '')
              .attr("color", data[i].color || '')
            img.onload = function () {
              imgBindEvent(data[i], a)
            }
          }
        }
        if (a) {
          a.attr('index', data[i].index || 0)
          a.attr('class', `ExcludeThisComponent ${a.attr('class') || ''}`)
          data[i].type !== "png" && bindDrag(a);
        }
      }
      if (rightProps.length > 0) {
        state.rightProps = rightProps;
        state.rightCard = rightProps;
        state.rightCardVisable = true;
      }
    };
    const imgBindEvent = (data, a) => {
      const canvasWidth = document.getElementById('svg').clientWidth
      const img_base_config = {
        x: data.x,
        y: data.y,
        minWidth: 1,
        minHeight: 1,
        width: +data.width,
        height: +data.height,
      }
      dragResizeInit(d3, g, a, img_base_config)
      if (data.text && data.color) {
        const text = g.append('text')
          .attr('class', 'temp-text-in-image')
          .attr('id', data.id + 'temp-text')
          .style('fill', data.color)
          .style('font-size', COMMON_CONFIG.getShowRowVal(canvasWidth, '14') + 'px')
          .text(data.text)
        const curr = document.getElementById(data.id + 'temp-text')
        text.attr("x", (+data.width / 2) + (+data.x) - (curr.clientWidth * 1.2 / 2))
          .attr("y", (+data.height / 2) + (+data.y) + curr.clientHeight * 2)
      }
      a.on("contextmenu", function (e) {
        if (!state.isEditting) return false
        e.preventDefault();
        contextMenu.visible = true
        contextMenu.left = e.clientX
        contextMenu.top = e.clientY - 5
        contextMenu.zIndex = d3.select(this).attr('index')
        contextMenu.target = d3.select(this).attr('id')
        document.addEventListener('click', function (e) {
          if (!document.getElementById('contextMenuContainer').contains(e.target)) {
            contextMenu.visible = false
          }
        })
      })
        .on("dblclick", function () {
          if (state.isEditting) {
            imgTextDialogVisible.value = true
            imgTextDialogParams.params = {
              id: data.id,
              text: data?.text || '',
              color: data?.color || '',
              width: data?.width || '',
              height: data?.height || ''
            }
          }
        })
    }
    const displayMessage = () => {
      const element = document.getElementById("d3CanvasView");
      const allChildren = element.querySelectorAll("*");
      allChildren.forEach((child, n) => {
        if (child.tagName === "foreignObject") {
          let data = child.children[0];
          //用来回显页面上的数字的------
          const value = state.wellData[child.getAttribute("data-formulaName")]
            ? formatNumber(
              state.wellData[child.getAttribute("data-formulaName")]
            ) : formatNumber(state.wellData[data.getAttribute("data-key")]);
          // : formatNumber(state.wellData[data.getAttribute("data-key")]) +
          // data.getAttribute("data-unit");
          d3.select(`#${data.getAttribute("data-id")}`)
            .attr("value", value || 'NULL')
            .style("color", value ? '#0bfcfd' : 'red')
            .style("font-family", value ? 'digital-7' : 'Arial');
        } else if (child.tagName === "text") {
          let data = child;
          const data_key = data.getAttribute("data-key");
          const value = state.wellData[data.getAttribute("data-formulaName")]
            ? formatNumber(
              state.wellData[data.getAttribute("data-formulaName")]
            )
            :
            // data.getAttribute("data-remark")  判断组件的remark，需要给唯一值
            formatNumber(
              state.wellData[data.getAttribute("data-key")],
              data.getAttribute("data-remark")
            ) + data.getAttribute("data-unit");
          d3.select(`#${data.getAttribute("data-id")}`).style(
            "color",
            "#ffffff"
          );
          if (data.getAttribute("data-keyType") !== "0") {
            const val = value || 'NULL'
            const color = value ? '#fff' : 'red'
            d3.select(`#${data.getAttribute("data-id")}`)
              .text(val)
              .style("fill", color)
          }

          if (data_key === "32") {
            // 获取文本内容
            data.style.fill = "#FFF";
            // if (child.textContent === "OFF") {
            //   data.style.fill = "#FFF";
            // }
            // if (child.textContent === "ON") {
            //   data.style.fill = "black";
            // }
          }
        }
      });
    };
    //输入框拖拽事件
    const bindDrag = selection => {
      let dx = 0;
      let dy = 0;
      let drag = function (event, d) {
        dx += event.dx;
        dy += event.dy;
        const _this = this;
        requestAnimationFrame(() => {
          d3.select(this)
            .attr("x", function () {
              return +d3.select(_this).attr("x") + dx;
            })
            .attr("y", function () {
              return +d3.select(_this).attr("y") + dy;
            });
          dx = dy = 0
        })
      };
      selection
        .call(
          d3
            .drag()
            .filter(function () {
              // 根据状态动态判断是否允许拖拽
              return state.isEditting; // 如果 isEditting 为 true，允许拖拽
            })
            .on("drag", drag)
        )
        .on("dblclick", function (event) {
          if (event.target.tagName === "image") return
          let arg = d3.select(this);
          if (state.AdIndex == '') {
            if (event.target.dataset.keytype == undefined) {
              state.tagsName = 'Text'
            } else if (event.target.dataset.keytype == '2') {
              state.tagsName = 'Input'
            } else if (event.target.dataset.keytype == '3') {
              state.tagsName = 'Formulas'
            }
          } else if (state.AdIndex == 0) {
            state.tagsName = 'Text'
          } else if (state.AdIndex == 1) {
            state.tagsName = 'Input'
          } else if (state.AdIndex == 2) {
            state.tagsName = 'Formulas'
          }
          const data =
            event.target.tagName === "INPUT"
              ? d3.select(this)?._groups[0][0]?.children[0]?.dataset
              : d3.select(this)?._groups[0][0].dataset;
          state.form = {
            keyType: arg.attr("data-keyType"),
            key: arg.attr("data-key"),
            x: arg.attr("x"),
            y: arg.attr("y"),
            width: arg.attr("width"),
            height: arg.attr("height"),
            valueColor: data.valuecolor || data.valueColor,
            valueFontSize: data.valuefontsize || data.valueFontSize,
            remark: data.remark || "",
            id: arg.attr("data-id"),
            formulaId: arg.attr("data-formulaId"),
            formulaText: "",
            otherWellId: arg.attr("tag-well-id")
          };
          state.formulaTag = { t0: "" };
          if (state.form.keyType.toString() === '3') {
            // const inputData = d3.select(this)._groups[0][0].children[0].dataset;
            const formulaText = d3.select(this)?._groups[0][0]?.getAttribute('data-formulaText')
            const formulaTag = d3.select(this)?._groups[0][0]?.getAttribute('data-formulaTag')
            state.form.formulaText = formulaText || ''
            state.formulaTag = JSON.parse(formulaTag) || '';
          }
          state.dialogVisible = true;
        })
        .on("contextmenu", function (event) {
          if (!state.isEditting) return false
          event.preventDefault();
          contextMenu.visible = false
          ElMessageBox.confirm(
            'Delete this component?',
            'Delete',
            {
              confirmButtonText: 'OK',
              cancelButtonText: 'Cancel',
              type: 'warning',
            }
          )
            .then(() => {
              d3.select(this).remove()
            })
        });
      selection
        .call(
          d3
            .drag()
            .filter(function () {
              // 根据状态动态判断是否允许拖拽
              return state.isEditting; // 如果 isEditting 为 true，允许拖拽
            })
            .on("drag", drag)
        )
        .on("click", function (event) {
          if (event.target) {
            const target = event.target;
            const id = target.id;
            const activeSvgElem = d3.selectAll('.elementActive')
            if (activeSvgElem['_groups'][0][0]) {
              activeSvgElem['_groups'][0].forEach(item => {
                const child = d3.select(item)
                child.attr('class', child.attr('class').replace('elementActive', '').trim())
              })
            }
            d3.select(target).attr('class', `${d3.select(target).attr('class')} elementActive`)
            if (target.tagName === "text") {
              if (!state.selectedTextIds.includes(id)) {
                d3.select(target).style("fill", "red");
                state.selectedTextIds.push(id);
              } else {
                d3.select(target).style("fill", "#ffffff");
                state.selectedTextIds = state.selectedTextIds.filter(
                  id => id !== target.id
                );
              }
            } else if (target.tagName === "INPUT") {
              if (!state.selectedTextIds.includes(id)) {
                d3.select(target)
                  .style("border-color", "red")
                  .style("border-width", "1PX");
                state.selectedTextIds.push(id);
              } else {
                d3.select(target).style("border-color", "#ffffff");
                state.selectedTextIds = state.selectedTextIds.filter(
                  id => id !== target.id
                );
              }
            }
          }
        });
    };

    const getTargetPosition = alignType => {
      const positionArr = [];
      state.selectedTextIds.forEach(id => {
        const tagName = d3.select(`#${id}`)._groups[0][0].tagName;
        const element =
          tagName === "INPUT"
            ? d3.select(`#${id}foreignObject`)
            : d3.select(`#${id}`);
        const x = parseFloat(element.attr("x")) || 0;
        const y = parseFloat(element.attr("y")) || 0; // 确保 y 属性存在
        const width = parseFloat(element.node().getBoundingClientRect().width);
        // const height = parseFloat(element.node().getBoundingClientRect().height); // 用于 top 对齐

        let position;
        if (alignType === "right") {
          position = x + width;
        } else if (alignType === "top") {
          position = y;
        } else {
          position = x;
        }

        positionArr.push(position);
      });

      if (alignType === "right") {
        return Math.max(...positionArr);
      } else if (alignType === "top") {
        return Math.min(...positionArr);
      } else {
        return Math.min(...positionArr);
      }
    };

    const alignLeft = () => {
      if (state.selectedTextIds.length === 0) {
        return ElMessage.warning("No selected text to align");
      }
      const targetX = getTargetPosition("left");
      state.selectedTextIds.forEach(id => {
        const tagName = d3.select(`#${id}`)._groups[0][0].tagName;
        if (tagName === "INPUT") {
          d3.select(`#${id}foreignObject`).attr("x", targetX);
        } else {
          d3.select(`#${id}`).attr("x", targetX);
        }
      });
    };

    const alignTop = () => {
      if (state.selectedTextIds.length === 0) {
        return ElMessage.warning("No selected text to align");
      }
      const targetY = getTargetPosition("top");
      state.selectedTextIds.forEach(id => {
        const tagName = d3.select(`#${id}`)._groups[0][0].tagName;
        const element =
          tagName === "INPUT"
            ? d3.select(`#${id}foreignObject`)
            : d3.select(`#${id}`);
        const height =
          tagName === "INPUT"
            ? parseFloat(element.node().getBoundingClientRect().height / 2)
            : parseFloat(element.attr("height"));
        if (tagName === "INPUT") {
          d3.select(`#${id}foreignObject`).attr("y", targetY);
        } else {
          d3.select(`#${id}`).attr("y", targetY);
        }
      });
    };

    const alignRight = () => {
      if (state.selectedTextIds.length === 0) {
        return ElMessage.warning("No selected text to align");
      }
      const targetRight = getTargetPosition("right");
      state.selectedTextIds.forEach(id => {
        const element = d3.select(`#${id}`);
        const width = parseFloat(element.node().getBoundingClientRect().width);
        const newX = targetRight - width;
        element.attr("x", newX);
      });
    };

    const padChange = (id) => {
      singleWell()

    }

    const handleCommand = (id) => {
      let nameId;
      let wellname;
      state.setValueData.forEach(item => {
        if (item.id === id) {
          nameId = item.label;
          wellname = item.wellName;
          console.log('找到匹配项，nameId:', nameId, 'wellname:', wellname);
        }
      });
      if (nameId === undefined || wellname === undefined) {
        console.log('未找到匹配的项，nameId:', nameId, 'wellname:', wellname);
      }
      const url = new URL(window.location.href);
      const params = new URLSearchParams(url.search);
      params.set('wellId', id);
      params.set('wellName', wellname);
      params.set('wellShowName', nameId);
      params.set('padId', state.padValue);
      url.search = params.toString();
      // location.reload(true);
      window.location.href = url.toString();
      state.selectedValue = id;
      console.log(window.location.href, 'window.location.href')
    };
    const addControl = command => {
      console.log(command, 'command')
      // // eslint-disable-next-line no-debugger
      // debugger
      if (state.iconComponents[command].type === "rightcard") {
        state.rightCardVisable = true;
        state.rightCard = RIGHT_SETTING;
      } else {
        drawPoints([
          {
            ...state.iconComponents[command],
            id: `uuid${generateRandomKey(20)}`
          }
        ]);
      }
      state.curIndex++
    }
    const dataSection = index => {
      console.log(index, 'ffffffffffff')
      state.AdIndex = index;
      drawPoints([
        {
          ...state.iconComponents[index],
          id: `uuid${generateRandomKey(20)}`
        }
      ]);
      state.curIndex++
    }
    const setInputStyle = () => {
      // 用d3获取所有的input 元素
      d3.selectAll("foreignObject input").each(function (d) {
        // 添加class
        d3.select(this).attr("class", "input-value");
        // unBindDrag(d3.select(this))
        bindClickEvent(d3.select(this), d3.select(this)._groups[0][0].dataset);
      });
      d3.selectAll("text").each(function (d) {
        d3.select(this).style("pointer-events", "none");
      });
      d3.selectAll(".drsElement").each(function (d) {
        d3.select(this).style("pointer-events", "none");
      });
    };
    const clearInputStyle = () => {
      unBindClickEvent(d3.selectAll(".input-value"));
      d3.selectAll(".input-value").attr("class", "");
      d3.selectAll("text").each(function (d) {
        d3.select(this)
          .style("pointer-events", "auto")
          .style("cursor", "pointer");
      });
      d3.selectAll(".drsElement").each(function (d) {
        d3.select(this).style("pointer-events", "auto");
      });
    };
    onMounted(async () => {
      getPadList();
      init();
      getTagType().then(res => {
        if (res?.code === 200) {
          res.data.sort((a, b) => a.value.charAt(0).toLowerCase() - b.value.charAt(0).toLowerCase());
          state.tagTypesList = res.data || [];
        }
      });
      queryList({ type: 1 }).then(res => {
        state.list = res.data || [];
        state.setValueData = []
        res.data.forEach(item => {
          state.setValueData.push({
            label: item.wellShowName,
            id: item.id,
            wellName: item.wellName
          })
        })
      });
      const wellId = route.query.wellId || "";
      if (wellId) {
        state.detailData.wellId = await wellId;
        await getWellHistory(wellId);
        await ProductionLast(wellId);
        await getDetail(wellId);
        await new Promise(resolve => {
          setTimeout(async () => {
            await getRealData(wellId);
            resolve();
          }, 1000); // 1000毫秒 = 1秒
        });
        await getFormulaDropList(wellId);
        pollInterval = setInterval(() => {
          getRealData(wellId);
        }, 300000);
      }
      const keyDownCopyFormat = (ele, randomKey) => {
        ele
          .attr('data-id', `${ele.attr('id')}_${randomKey}`)
          .attr('id', `${ele.attr('id')}_${randomKey}`)
          .attr('class', ele.attr('class').replace('elementActive', '').trim())
      }
      let keyDownCopyLock = false
      document.addEventListener('keydown', function (e) {
        const keyCode = e.keyCode.toString()
        if (state.isEditting && e.shiftKey && keyCode === '68' && !keyDownCopyLock) {
          keyDownCopyLock = true
          let target = d3.select('.elementActive')
          if (target['_groups'][0][0]) {
            const randomKey = generateRandomKey(18)
            const tagName = target['_groups'][0][0].tagName.toLowerCase()
            if (tagName === 'input') {
              target = d3.select(`#${target.attr('id')}foreignObject`)
            }
            const output = target.clone(true)
            output
              .attr('x', +target.attr('x') + 15)
              .attr('y', +target.attr('y') + 15)
            if (tagName === 'image') {
              output
                .attr('class', 'ExcludeThisComponent')
                .attr('id', `${output.attr('id')}${randomKey}`)
              imgBindEvent({
                x: output.attr('x'),
                y: output.attr('y'),
                width: output.attr('width'),
                height: output.attr('height'),
                text: output.attr('text'),
                color: output.attr('color'),
                id: output.attr('id')
              }, output)
            } else {
              keyDownCopyFormat(tagName === 'input' ? output.select('input') : output, randomKey)
              bindDrag(output)
            }
          }
          keyDownCopyLock = false
        }
      })
    });
    onBeforeUnmount(() => {
      clearInterval(pollInterval);
      document.addEventListener('keydown', null);
    });
    watchEffect(() => {
      if (state.isEditting) {
        clearInputStyle();
        createGridBackground(40);
      } else {
        setInputStyle();
      }
    });
    const edit = () => {
      state.isEditting = true;
      state.rightCardCollapsed = true;
      dragResizeOpen()
    };
    //提交事件
    const submit = () => {
      state.isEditting = false;
      dragResizeClose()
      d3.selectAll('.temp-text-in-image').remove()
      d3.selectAll('.copy-move-group-outline').remove()
      const element = document.getElementById("d3CanvasView");
      const allChildren = element.querySelectorAll("*");
      let pointData = [canvasSizeConfig.value];
      let c = 0;
      allChildren.forEach((child) => {
        c++
        if (child.tagName === "text") {
          let item = {
            x: child.x ? COMMON_CONFIG.getOriginRowVal(child.x.baseVal[0].value) || 0 : "",
            y: child.y ? COMMON_CONFIG.getOriginColVal(child.y.baseVal[0].value) || 0 : "",
            width: child.width ? COMMON_CONFIG.getOriginRowVal(child.width.baseVal.value) : "",
            height: child.height ? COMMON_CONFIG.getOriginColVal(child.height.baseVal.value) : "",
            id: `uuid${c}`,
            index: c,
            keyType: child.getAttribute("data-keyType") || "",
            pid: child.getAttribute("data-pid") || "",
            key: child.getAttribute("data-key") || "",
            value: child.getAttribute("data-value") || "",
            unit: child.getAttribute("data-unit") || "",
            desc: child.getAttribute("data-desc") || "",
            valueColor: child.getAttribute("data-valueColor") || "",
            valueFontSize: COMMON_CONFIG.getOriginRowVal(child.getAttribute("data-valueFontSize")) || "",
            className: child.getAttribute("data-className") || "",
            type: child.getAttribute("data-type") || "",
            remark: child.getAttribute("data-remark") || "",
            external: []
          };
          if (item.keyType.toString() === '3') {
            //这里应该是保存用的---------
            // item.formula = {
            //   formulaName: child.getAttribute("data-formulaName") || "",
            //   formulaText: child.getAttribute("data-formulaText") || "",
            //   formulaTag: child.getAttribute("data-formulaTag") ? JSON.parse(child.getAttribute("data-formulaTag")) : ''
            // };
            item.formula = {
              elementId: child.getAttribute("data-formulaName") || "",
              formulaId: child.getAttribute("data-formulaId") || "",
            };
            // item.formula.formulaText = btoa(item.formula.formulaText)
          }
          pointData.push(item);
        } else if (child.tagName === "svg") {
          let item = {
            x: child.x ? COMMON_CONFIG.getOriginRowVal(child.x.baseVal.value) : "",
            y: child.y ? COMMON_CONFIG.getOriginColVal(child.y.baseVal.value) : "",
            width: child.width ? COMMON_CONFIG.getOriginRowVal(child.width.baseVal.value) : "",
            height: child.height ? COMMON_CONFIG.getOriginColVal(child.height.baseVal.value) : "",
            id: `uuid${c}`,
            index: c,
            keyType: child.getAttribute("data-keyType") || "",
            pid: child.getAttribute("data-pid") || "",
            key: child.getAttribute("data-key") || "",
            value: child.getAttribute("data-value") || "",
            unit: child.getAttribute("data-unit") || "",
            desc: child.getAttribute("data-desc") || "",
            valueColor: child.getAttribute("data-valueColor") || "",
            valueFontSize: COMMON_CONFIG.getOriginRowVal(child.getAttribute("data-valueFontSize")) || "",
            className: child.getAttribute("data-className") || "",
            type: child.getAttribute("data-type") || "",
            remark: child.getAttribute("data-remark") || "",
            external: []
          };
          pointData.push(item);

        } else if (child.tagName === "foreignObject") {
          let data = child.children[0];
          let item = {
            x: child.x ? COMMON_CONFIG.getOriginRowVal(child.x.baseVal.value) : "",
            y: child.y ? COMMON_CONFIG.getOriginColVal(child.y.baseVal.value) : "",
            width: child.width ? COMMON_CONFIG.getOriginRowVal(child.width.baseVal.value - 10) : "",
            height: child.height ? COMMON_CONFIG.getOriginColVal(child.height.baseVal.value - 10) : "",
            id: `uuid${c}`,
            index: c,
            keyType: data.getAttribute("data-keyType") || "",
            pid: data.getAttribute("data-pid") || "",
            key: data.getAttribute("data-key") || "",
            value: data.getAttribute("data-value") || "",
            unit: data.getAttribute("data-unit") || "",
            desc: data.getAttribute("data-desc") || "",
            valueColor: data.getAttribute("data-valueColor") || "",
            valueFontSize: COMMON_CONFIG.getOriginRowVal(data.getAttribute("data-valueFontSize")) || "",
            className: data.getAttribute("data-className") || "",
            tagWellId: data.getAttribute("tag-well-id") || "",
            type: "input",
            remark: data.getAttribute("data-remark") || ""
          };
          if (item.keyType.toString() === '3') {
            item.formula = {
              // formulaName: data.getAttribute("data-id") || "",
              // formulaText: data.getAttribute("data-formulaText") || "",
              // formulaTag: JSON.parse(data.getAttribute("data-formulaTag"))
              elementId: data.getAttribute("data-id") || "",
              formulaId: data.getAttribute("data-formulaId") || "",
            };
          } else {
            delete item.formula;
          }
          pointData.push(item);
        } else if (child.tagName === "line") {
          const x1 = COMMON_CONFIG.getOriginRowVal(child.x1.baseVal.value) || 0;
          const y1 = COMMON_CONFIG.getOriginColVal(child.y1.baseVal.value) || 0;
          const x2 = COMMON_CONFIG.getOriginRowVal(child.x2.baseVal.value) || 0;
          const y2 = COMMON_CONFIG.getOriginColVal(child.y2.baseVal.value) || 0;
          let item = {
            x: x1,
            y: y1,
            width: (x2 - x1),
            height: (y2 - y1),
            type: "line",
            keyType: "",
            key: "",
            value: "",
            unit: "",
            valueColor: "#D2D2D2",
            remark: ""
          };
          if (item.width && item.height) {
            pointData.push(item);
          }
        } else if (child.tagName === 'image') {
          let item = {
            x: child.x ? COMMON_CONFIG.getOriginRowVal(child.x.baseVal.value) : "",
            y: child.y ? COMMON_CONFIG.getOriginColVal(child.y.baseVal.value) : "",
            width: child.width ? COMMON_CONFIG.getOriginRowVal(child.width.baseVal.value) : "",
            height: child.height ? COMMON_CONFIG.getOriginColVal(child.height.baseVal.value) : "",
            id: `uuid${c}`,
            index: child.getAttribute("index") || 0,
            keyType: child.getAttribute("data-keyType") || "",
            text: child.getAttribute('text') || '',
            color: child.getAttribute('color') || '',
            imageUrl: child.getAttribute('imageUrl'),
            belongToImage: true,
            type: "png",
          };
          if (item.width && item.height && item.imageUrl) {
            pointData.push(item);
          }
        }
      });
      const result = pointData
        .concat(toRaw(state.rightCard))
        .concat(
          (state.btmTableData || []).filter(
            item => Object.keys(item).length > 0
          )
        )
        .concat(state.detailData.otherItems || []);
      editDetail(result);
    };
    const cancel = () => {
      state.isEditting = false;
      dragResizeClose()
      window.location.reload();
    };
    const groupByType = items => {
      return items.reduce(
        (acc, item) => {
          acc.configJson.push(item);
          return acc;
        },
        { configJson: [] }
      );
    };
    //初始化井tag
    const getDetail = async wellId => {
      getWellTag(wellId).then(res => {
        if (res?.code === 200) {
          res.data.sort((a, b) => a.tagName.toUpperCase() - b.tagName.toUpperCase());
          state.tagsList = res.data || [];
        }
      });
      const res = await getConfig(wellId);
      if (res.code === 200) {
        const data = res.data || {};
        state.uuindValue = data.configJson;
        state.detailData.imageUrl = data.imageUrl || "";
        state.detailData.configJson = data.configJson || [];
        state.detailData.id = data.id || "";
        if (state.detailData.configJson.length > 0) {
          if (state.detailData.configJson[0].type === 'canvasSizeSetting') {
            const config = state.detailData.configJson.splice(0, 1)[0]
            canvasSizeConfig.value.width = parseInt(config.width)
            canvasSizeConfig.value.height = parseInt(config.height)
            canvasSizeChange()
          }
          const groupedData = groupByType(state.detailData.configJson);
          state.detailData.otherItems = groupedData["otherItems"] || [];
          drawPoints(groupedData["configJson"]);
          nextTick(() => {
            setInputStyle();
          });
        }
        state.rightCardCollapsed = false;
        console.log(data, 'data------！')
      } else {
        ElMessage.error(res.msg);
      }
    };
    //编辑井详情
    const editDetail = async data => {
      const loading = ElLoading.service({
        lock: true,
        text: 'Loading',
        background: 'rgba(0, 0, 0, 0.7)',
      })
      state.detailData.imageUrl = await handleConvertAndUpload();
      state.tagsList = [];
      data.forEach(item => {
        if (item.keyType === '3') {
          let encoder = new TextEncoder();
          let bytes = encoder.encode(item.formula.formulaText);
          let binaryString = String.fromCharCode(...bytes);
          item.formula.formulaText = btoa(binaryString);
        }
      })
      let param = {
        id: state.detailData.id,
        wellId: state.detailData.wellId,
        configJson: data,
        imageUrl: state.detailData.imageUrl
      };
      param.configJson.forEach(item => {
        if (item.formula) {
          if (item.formula.formulaTag === "") {
            item.formula.formulaTag = {};
          }
        }
      });

      if (param.id === "") {
        const res = await addConfig(param);
        if (res.code === 200) {
          await ElMessage.success("added success");
          // window.location.reload();
        } else {
          ElMessage.error(res.msg);
        }
      } else {
        const res = await editConfig(param);
        if (res.code === 200) {
          await ElMessage.success("updated success");
          // window.location.reload();
        } else {
          ElMessage.error(res.msg);
        }
      }
      loading.close();
      window.location.reload();
    };
    const getRealData = async wellId => {
      const data = {
        wellId
      };
      await getWellRealData(data)
        .then(res => {
          if (res.code == 200) {
            state.wellName = res.data.wellName;
            state.wellnameid = res.data.wellName;
            state.selectedValue = res.data.wellId;
            state.wellidNum = res.data.wellId;
            state.espname = res.data.wellName;
            if (res.data.isRedrill == true) {
              state.isredrill = "R";
            }
            state.wellTestStatus = res.data.wellTestStatus;
            // 确保 "32" 属性存在，如果不存在则初始化为 "OFF"
            const numValue = Number(res.data.wellTagTypeInfoList["32"]);
            res.data.wellTagTypeInfoList["32"] = numValue === 0 ? "OFF" : "ON";
            // console.log(res.data.wellTagTypeInfoList["32"],'pppppppppppppp')
            // if (!res.data.wellTagTypeInfoList["10000"]) {
            //   res.data.wellTagTypeInfoList["32"] = "OFF";
            // }
            // console.log(res.data.wellTagTypeInfoList["32"],'res.data.wellTagTypeInfoList')
            // res.data.wellTagTypeInfoList["32"] =
            //   res.data.wellTagTypeInfoList["32"] === "1.00" ? "ON" : "OFF";
            state.wellData = {
              ...res.data.wellTagInfoList,
              ...res.data.wellTagTypeInfoList,
              ...res.data.wellTagFormulaInfoList
            };
            displayMessage();
          }
        })
        .catch(error => {
          // console.log(error, "error");
        });
    };
    const getWellHistory = async wellId => {
      let formData = new FormData();
      formData.append("wellid", wellId);
      queryWellHistory(formData).then(res => {
        if (res.code == 200) {
          state.scrollModelData = res.data;
        }
      });
    };
    const changeData = () => {
    };
    let pollInterval = null;

    const addFormulaTag = () => {
      const formulaTag = state.formulaTag;
      const maxAttempts = 10;
      const tagNames = Object.keys(formulaTag);
      for (let i = 0; i < maxAttempts; i++) {
        if (!tagNames.includes(`t${i}`)) {
          state.formulaTag[`t${i}`] = "";
          break;
        }
      }
    };
    const completion = () => {
      state.isTrendpad = false;
      state.isTrendtag = false;
    };
    const exportHistory = async () => {
      exportWellHistory(state.detailData.wellId).then(blob => {
        exportFile(blob, `${state.wellName}.txt`);
      });
    };
    const openEspTrend = () => {
      state.isTrendpad = !state.isTrendpad;
    };
    const goBack = () => {
      window.parent.postMessage({ type: 'goBigscreen' }, '*');
    };
    const { isConverting, error, convertToImage } = useHtmlToImage(
      "#contentToConvert",
      "converted-image.png"
    );
    const handleConvertAndUpload = async () => {
      const blob = await convertToImage();
      if (blob) {
        const formData = new FormData();
        formData.append("file", blob, "converted-image.png");
        formData.append("modelName", "wellInfo");
        const res = await uploadFile(formData);
        if (res.code === 200) {
          return res.msg;
        } else {
          return "";
        }
        // window.location.reload()
      }
    };

    const handleChildEvent = (data) => {
      state.setValueData.forEach(item => {
        if (item.id == data) {
          state.espname = item.label
        }
      })
    }
    // const openInportDialog = (index) => {
    //   // state.originWellId = "";
    //   // state.previewSrcList = [];
    //   // state.importWellDialogVisible = true;
    // };
    const onSelectWellChange = async id => {
      try {
        const res = await getImageUrl(id);
        if (res.code === 200) {
          state.imgMsg = res.msg;
          const blob = await downloadFile(res.msg);
          state.previewSrcList = [URL.createObjectURL(blob)];
        }
      } catch (error) {
        ElMessage.error("No template");
      }
    };
    const onCopyClick = async (index) => {
      try {
        // 显示确认对话框
        await ElMessageBox.confirm(
          'Whether to replace the page with the current template?',
          'Prompts',
          {
            confirmButtonText: 'OK',
            cancelButtonText: 'Cancel',
            type: 'warning',
          }
        );
        // 根据索引确定sourceWellId（从1开始）
        const sourceWellId = (index + 1).toString();
        // 调用复制API
        const res = await copyWell({
          sourceWellId,
          destWellId: state.detailData.wellId
        });
        if (res.code === 200) {
          ElMessage.success("Copy Success");
          const url = new URL(window.location.href);
          url.searchParams.set('wellId', sourceWellId);
          window.location.href = url.toString();
        } else {
          ElMessage.error(res.msg);
        }
      } catch (error) {
        // 用户点击了取消按钮或发生其他错误
        console.log('Operation canceled or error occurred:', error);
      }
    };
    const groundItem = () => {
      state.selectedValue = '';
    }
    const changeTrend = () => {
      let token = localStorage.getItem('access_token')
      if (token) {
        //
      } else {
        window.parent.postMessage({ type: 'needLogin' }, '*');
      }
    }

    return {
      ...toRefs(state),
      getSvg,
      groundItem,
      wellTestStatusFlag,
      wellTestStatusFlagColor,
      handleChildEvent,
      setInputStyle,
      edit,
      cancel,
      submit,
      addControl,
      handleCommand,
      padChange,
      getDetail,
      getFormulaDropList,
      editDetail,
      setCard,
      getTagByKeyType,
      handleMouseEnter,
      handleMouseOut,
      updateJson,
      displayMessage,
      changeData,
      addFormulaTag,
      completion,
      exportHistory,
      openEspTrend,
      goBack,
      isConverting,
      error,
      changeTag,
      // openInportDialog,
      onSelectWellChange,
      onCopyClick,
      alignLeft,
      alignRight,
      alignTop,
      handleData,
      zLevelChange,
      canvasSizeChange,
      imgTextDialogVisible,
      imgTextDialogParams,
      contextMenu,
      canvasSizeConfig,
      changeTrend,
      openFavoriteList,
      rowDbclickFun,
      deleteClick,
      wellManageGetAllList,
      getFormulaManageList,
      handlePageChange,
      presetFormulas,
      addpointsFun,
      removeFormulaTag,
      formulaManageDeleteFun,
      SubAddPreseForm,
      addPreseFormFun,
      editPreseIdClick,
      formRef,
      getPadList,
      singleWell,
      presePadChange,
      changelist,
      ground,
      updatePaginatedOptions,
      handleRemoteMethod,
      selecthandlePageChange,
      toggleRightCard,
      dataSection
    };
  }
}
  ;
</script>

<style>
.selectCls {
  height: 390px;

  .el-scrollbar__wrap {
    overflow: visible;

  }

  .el-scrollbar__thumb {
    display: none;
  }
}
</style>

<style scoped>
.dialog-footer {
  text-align: right;
  display: flex;
  justify-content: flex-end;
}

.pagination-right {
  display: flex;
  justify-content: flex-end !important;
}

::v-deep .el-table__body tr.current-row>td.el-table__cell {
  background-color: rgb(209 226 244);
}
</style>

<style lang="scss" scoped>
:deep svg {
  user-select: none
}

.preset-well {
  display: flex;
  justify-content: space-between;
}

.top_control {
  justify-content: end;
  padding: 10px 10px 0 0;
}

.well-name {
  color: #ffffff;
  font-size: 2.8vh;
  font-weight: bold;
  flex: 1;
}

.el-button {
  font-size: 1.2vh !important;
  padding: 1.5vh !important;
}

.wellrednum {
  color: red;
  font-size: 24px;
  font-weight: bold;
  flex: 1;
  right: 65rem;
  position: absolute;
}

.well-status {
  color: #ffffff;
  font-size: 1.8vh;
  display: flex;
  align-items: center;
  justify-content: right;
}

.flag {
  font-size: 2.5vh;
  font-weight: bold;
  margin-left: 5px;
}

#d3CanvasView {
  width: 100vw;
  height: calc(100% - 50px);
  display: flex;
  position: relative;
}

.binding-container-img {
  display: flex;
  flex-wrap: wrap;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
}

.binding-item-img {
  display: flex;
  flex-direction: column;
  align-items: center;
  padding: 6px 8px;
  cursor: pointer;
}

/* 图片容器样式 */
.image-wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-bottom: 4px;
}

/* 图片样式：固定尺寸，避免拉伸 */
.binding-img-two {
  width: 1.875rem;
  height: 1.875rem;
  object-fit: contain;
}

.binding-label-img {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  color: #fff;
  font-size: 0.75rem;
  text-align: center;
}

.binding-item {
  padding: 0.3rem 8px;
  display: flex;
  align-items: center;
  gap: 5px;
  color: #fff;
  font-size: 0.8rem;
  cursor: pointer;
}

/* 图片样式：固定尺寸，避免拉伸 */
.binding-img {
  width: 1.25rem;
  height: 1.25rem;
  object-fit: contain;
  vertical-align: middle;
}

.binding-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  padding-top: 0.2rem;
  line-height: 1;
  /* 文字行高与图片高度匹配 */
}

#d3Canvas {
  flex: 1;
  z-index: 20;
  overflow: auto;
}

#d3Canvas::-webkit-scrollbar {
  width: 8px;
  height: 8px;
}

#d3Canvas::-webkit-scrollbar-thumb {
  background-color: #888;
  border-radius: 6px;
}

#d3Canvas::-webkit-scrollbar-track,
#d3Canvas::-webkit-scrollbar-corner {
  background-color: transparent;
}

#d3Canvas::-webkit-scrollbar-thumb:horizontal {
  width: 6px;
}

#right-card {
  width: 20%;
  padding-right: 10px;
  margin-right: 10px;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  height: 100%;
  transition: all 0.3s ease;
  /* 新增：过渡动画 */
}

/* 新增：右侧展开/收起按钮样式 */
#rightToggleBtn {
  width: 24px;
  height: 60px;
  background-color: #409eff;
  color: white;
  border: none;
  border-radius: 5px;
  cursor: pointer;
  z-index: 30;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  align-self: center;
  transition: all 0.3s ease;

  &:hover {
    background-color: #66b1ff;
  }
}

#left_card {
  width: 360px;
  display: flex;
  background: rgb(18, 26, 50);
  flex-direction: column;
  height: 100%;
  overflow-x: hidden;
  /* 禁止水平滚动 */
  overflow-y: auto;
  /* 垂直方向超出时显示滚动条 */
}

#numericheading {
  width: 100%;
  height: 2%;
  display: flex;
  text-align: left;
  font-weight: 600;
  color: #fff;
  margin-top: 0.2rem;
  font-size: .875rem;
}

#left_card::-webkit-scrollbar {
  width: 6px;
  /* 滚动条宽度 */
}

#left_card::-webkit-scrollbar-track {
  background: transparent;
  /* 轨道背景透明 */
}

#left_card::-webkit-scrollbar-thumb {
  background-color: rgba(150, 150, 150, 0.5);
  /* 滚动条颜色 */
  border-radius: 3px;
  /* 滚动条圆角 */
}

#left_card::-webkit-scrollbar-thumb:hover {
  background-color: rgba(100, 100, 100, 0.7);
  /*  hover时颜色加深 */
}

#svg {
  position: absolute;
  left: 0;
  top: 0;
}

.drsElement {
  position: absolute;
}

:deep .drsMoveHandle {
  height: 20px;
  background: transparent;
  cursor: move;
  font-size: 14px;
}

:deep .dragresize {
  position: absolute;
  width: 5px;
  height: 5px;
  font-size: 1px;
  background: #eee;
  border: 1px solid #333;
}

:deep .dragresize-tl {
  top: -8px;
  left: -8px;
  cursor: nw-resize;
}

:deep .dragresize-tm {
  top: -8px;
  left: 50%;
  margin-left: -4px;
  cursor: n-resize;
}

:deep .dragresize-tr {
  top: -8px;
  right: -8px;
  cursor: ne-resize;
}

:deep .dragresize-ml {
  top: 50%;
  margin-top: -4px;
  left: -8px;
  cursor: w-resize;
}

:deep .dragresize-mr {
  top: 50%;
  margin-top: -4px;
  right: -8px;
  cursor: e-resize;
}

:deep .dragresize-bl {
  bottom: -8px;
  left: -8px;
  cursor: sw-resize;
}

:deep .dragresize-bm {
  bottom: -8px;
  left: 50%;
  margin-left: -4px;
  cursor: s-resize;
}

:deep .dragresize-br {
  bottom: -8px;
  right: -8px;
  cursor: se-resize;
}

:deep .editable {
  cursor: text;
}

.footer {
  width: 80%;
  display: block;
  position: absolute;
  bottom: 0;
  right: 0;
}

:deep foreignObject {
  position: relative;

  input {
    color: #fff;
    background: transparent;
    position: absolute;
    left: 0 !important;
    top: 0 !important;
    text-align: right;
    border: 1px solid #ffffff;
  }
}

:deep .input-value {
  display: inline-block;
  text-align: right;
  font-family: "digital-7";
  font-weight: 600;
  letter-spacing: 3px;
  cursor: pointer;
  outline: none;
  user-select: none !important;
  background: rgba(0, 0, 0, 0);
  position: absolute;
  left: 0;
  top: 0;
  border: none;
}

:deep .input-class {
  /* 保留原有注释 */
}

.el-dropdown__popper .el-dropdown-menu {
  max-height: 450px;
}

.dialog {
  width: 96%;
  height: 95%;
  position: absolute;
  top: 4%;
  left: 3%;
  background: url("@/assets/popver_Bg.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  display: flex;
  justify-content: flex-start;
  flex-direction: column;
  align-items: center;
  z-index: 99;
}

.tooltip-content {
  width: 15%;
  height: auto;
  padding: 10px;
  position: absolute;
  background: url("@/assets/popver_Bg.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  display: flex;
  justify-content: flex-start;
  flex-direction: column;
  text-align: left;
  z-index: 99;
  color: #fff;

  span {
    display: inline-block;
    width: 42px;
  }
}

.tooltip-row {
  display: flex;
  justify-content: flex-start;
  align-items: center;
}

.dialog-title {
  left: 30%;
  width: 40%;
  height: 9%;
  background: url("@/assets/header_bg.png") no-repeat;
  background-size: 100%;
  background-position: 50% -90%;
  color: rgb(17, 137, 229);
  font-size: 20px;
  line-height: 60px;
  font-weight: bolder;
}

.dialog-box {
  width: 100%;
  height: 100%;
}

.el-icon-close {
  color: #ffffff;
  position: absolute;
  top: 0.5443rem;
  right: 1.6432rem;
  font-size: 2.2865rem;
  cursor: pointer;
}
</style>
